package com.xbts.system.service.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xbts.common.core.domain.entity.SysUser;
import com.xbts.common.core.domain.model.LoginUser;
import com.xbts.common.core.redis.RedisDelayQueueUtil;
import com.xbts.common.enums.RedisDelayQueueEnum;
import com.xbts.common.exception.ServiceException;
import com.xbts.common.utils.SnowFlakeUtil;
import com.xbts.system.enums.PayStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xbts.system.mapper.CnBalanceOrderMapper;
import com.xbts.system.domain.CnBalanceOrder;
import com.xbts.system.service.ICnBalanceOrderService;
import com.xbts.common.utils.DateUtils;
import com.xbts.common.utils.SecurityUtils;

/**
 * 余额充值订单Service业务层处理
 *
 * @author xbts
 * @date 2023-08-16
 */
@Service
public class CnBalanceOrderServiceImpl extends ServiceImpl<CnBalanceOrderMapper, CnBalanceOrder> implements ICnBalanceOrderService {

    @Autowired
    private RedisDelayQueueUtil redisDelayQueueUtil;

    /**
     * 查询余额充值订单列表
     *
     * @param cnBalanceOrder 余额充值订单
     * @return 余额充值订单
     */
    @Override
    public List<CnBalanceOrder> selectCnBalanceOrderList(CnBalanceOrder cnBalanceOrder) {
        SecurityUtils.getLoginUser();
        QueryWrapper<CnBalanceOrder> queryWrapper = cnBalanceOrder.queryWrapper();
        if (cnBalanceOrder.getParams() != null) {
            // 开始时间
            if (cnBalanceOrder.getParams().get("startTime") != null) {
                queryWrapper.ge("payment_time", cnBalanceOrder.getParams().get("startTime"));
            }
            // 结束时间
            if (cnBalanceOrder.getParams().get("endTime") != null) {
                queryWrapper.le("payment_time", cnBalanceOrder.getParams().get("endTime"));
            }
        }

        // 管理员查询所有,用户查询自己的余额充值订单
        if (!SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            queryWrapper.eq("user_id", cnBalanceOrder.getUserId());
        }
        queryWrapper.orderByDesc("create_time");
        return list(queryWrapper);
    }

    /**
     * 查询余额充值订单
     *
     * @param balanceId 余额充值订单主键
     * @return 余额充值订单
     */
    @Override
    public CnBalanceOrder selectCnBalanceOrderByBalanceId(String balanceId) {
        return getById(balanceId);
    }

    /**
     * 新增余额充值订单
     *
     * @param cnBalanceOrder 余额充值订单
     * @return 结果
     */
    @Override
    public CnBalanceOrder insertCnBalanceOrder(CnBalanceOrder cnBalanceOrder) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        String sn = SnowFlakeUtil.createStr("CN");

        cnBalanceOrder.setSn(sn);
        cnBalanceOrder.setAmount(new BigDecimal("0.01"));
        cnBalanceOrder.setUserName(user.getUserName());
        cnBalanceOrder.setUserId(user.getUserId());
        cnBalanceOrder.setPayStatus(PayStatusEnum.UNPAID);
        cnBalanceOrder.setBalanceId(SnowFlakeUtil.getSnowFlakeId().toString());
        cnBalanceOrder.setCreateBy(SecurityUtils.getUserId().toString());
        boolean save = save(cnBalanceOrder);
        if (!save) {
            throw new ServiceException("订单创建失败，请稍后重试");
        }
        // 30分钟后自动取消订单
        Map<String, String> map = new HashMap<>();
        map.put("balanceId", cnBalanceOrder.getBalanceId());
        map.put("remark", "订单支付超时，自动取消订单");
        redisDelayQueueUtil.addDelayQueue(map, 1, TimeUnit.MINUTES, RedisDelayQueueEnum.CN_BALANCE_ORDER_CANCEL.getCode());
        return cnBalanceOrder;
    }

    /**
     * 修改余额充值订单
     *
     * @param cnBalanceOrder 余额充值订单
     * @return 结果
     */
    @Override
    public boolean updateCnBalanceOrder(CnBalanceOrder cnBalanceOrder) {
        cnBalanceOrder.setUpdateBy(SecurityUtils.getUserId().toString());
        cnBalanceOrder.setUpdateTime(DateUtils.getNowDate());
        return updateById(cnBalanceOrder);
    }

    /**
     * 批量删除余额充值订单
     *
     * @param balanceIds 需要删除的余额充值订单主键
     * @return 结果
     */
    @Override
    public boolean deleteCnBalanceOrderByBalanceIds(List<String> balanceIds) {
        return removeBatchByIds(balanceIds);
    }

    /**
     * 删除余额充值订单信息
     *
     * @param balanceId 余额充值订单主键
     * @return 结果
     */
    @Transactional
    @Override
    public boolean deleteCnBalanceOrderByBalanceId(String balanceId) {
        return removeById(balanceId);
    }

    @Override
    public CnBalanceOrder queryDetail(String sn) {
        QueryWrapper<CnBalanceOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sn", sn);
        return getOne(queryWrapper);
    }

    @Override
    public void cancelTimeoutOrder() {
        QueryWrapper<CnBalanceOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pay_status", PayStatusEnum.UNPAID);
        queryWrapper.le("create_time", DateUtils.addMinutes(DateUtils.getNowDate(), -30));
        List<CnBalanceOrder> list = list(queryWrapper);
        if (list != null && list.size() > 0) {
            for (CnBalanceOrder cnBalanceOrder : list) {
                cnBalanceOrder.setPayStatus(PayStatusEnum.CANCEL);
            }
            updateBatchById(list);
        }
    }

    @Override
    public CnBalanceOrder paymentSuccess(String sn) {
        LambdaQueryWrapper<CnBalanceOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CnBalanceOrder::getSn, sn);
        CnBalanceOrder cnBalanceOrder = getOne(queryWrapper);
        if (cnBalanceOrder == null) {
            throw new ServiceException("订单不存在");
        }
        cnBalanceOrder.setPayStatus(PayStatusEnum.PAID);
        updateById(cnBalanceOrder);
        return cnBalanceOrder;
    }
}
